home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / ab20_archive / utilities / printer / post-1.6src.lzh / postband.c < prev    next >
C/C++ Source or Header  |  1991-04-17  |  21KB  |  812 lines

  1. /* Band rendering print driver for Post V1.6.  File "postband.c"
  2.  * (C) Adrian Aylward 1989, 1991
  3.  *
  4.  * You may freely copy, use, and modify this file.
  5.  *
  6.  * This file is a PostScript program driver that splits a PostScript file
  7.  * that conforms to the structuring conventions and calls Post to print
  8.  * it in a series of bands, even if there is not enough memory for a full
  9.  * page buffer.  It is totally Amiga specific.
  10.  *
  11.  * The program was tested using Lattice C V5.05.  It has various Lattice
  12.  * dependencies.
  13.  */
  14.  
  15. # include <dos.h>
  16. # include <devices/printer.h>
  17. # include <devices/prtbase.h>
  18. # include <exec/exec.h>
  19. # include <exec/execbase.h>
  20. # include <exec/tasks.h>
  21. # include <graphics/gfx.h>
  22. # include <graphics/rastport.h>
  23. # include <proto/dos.h>
  24. # include <proto/exec.h>
  25. # include <stdio.h>
  26. # include <string.h>
  27.  
  28. # include "postlib.h"
  29.  
  30. /* Assembler routines */
  31.  
  32. extern void insertbreak(void);
  33. extern void deletebreak(void);
  34. extern void insertftrap(void);
  35. extern void deleteftrap(void);
  36.  
  37. /* Routines defined and referenced only within this module */
  38.  
  39. extern void prints(BPTR fh, char *string);
  40. extern void errmsg(char *string);
  41. extern void setprinter(void);
  42. extern void setprintden(void);
  43. extern int  strtoint(char **sp, int *ip);
  44. extern void __saveds __asm copypage(register __d0 int num);
  45. extern void printpage(void);
  46. extern void splitpage(void);
  47.  
  48. /* External data (initialised to zero) */
  49.  
  50. int retcode, errcode, ioerror;
  51.  
  52. int arec;
  53.  
  54. BPTR errfh;
  55.  
  56. int ybase;
  57. int prologue, trailer;
  58. FILE *printfile;
  59.  
  60. struct library *PSbase;
  61. struct PSparm parm;
  62.  
  63. struct BitMap bitmap;
  64. struct ColorMap colormap;
  65.  
  66. int propen, prden;
  67. struct IODRPReq prreq;
  68. struct PrinterData *prdata;
  69. struct PrinterExtendedData *prextdata;
  70. struct Preferences *prprefs;
  71. struct RastPort prrast;
  72. struct MsgPort *prport;
  73. ULONG prsig;
  74. UBYTE prstatus[2];
  75.  
  76. int breakset, ftrapset;
  77.  
  78. /* Colour tables.  The default color map type is a vector or UWORD RGB
  79.  * values.  The colours are inverted as we set a bit in the bitmap whenever
  80.  * we want to place a drop of (black or cyan/magenta/yellow) ink */
  81.  
  82. static UWORD bcolors[2] =  /* Black and white */
  83. {   0xfff, 0x000                /* White   black */
  84. };
  85.  
  86. static UWORD ccolors[16] = /* Colour (RGB or CMYK) */
  87. {   0xfff, 0x0ff, 0xf0f, 0x00f, /* White   cyan    magenta blue */
  88.     0xff0, 0x0f0, 0xf00, 0x000, /* Yellow  green   red     black */
  89.     0x000, 0x000, 0x000, 0x000, /* Black */
  90.     0x000, 0x000, 0x000, 0x000  /* Black */
  91. };
  92.  
  93. /* Arguments */
  94.  
  95. int argfilec, argsizec, argmemc;
  96. char *argprint;
  97. char *argfilev[5], *argsizev[5], *argmemv[5];
  98. char *argkey[] =
  99. {   "PRINT", "SIZE", "MEM", NULL };
  100.  
  101. /* Startup code */
  102.  
  103. extern void main(int argc, char **argv);
  104.  
  105. void _main(char *line)
  106. {   char *argv[32];
  107.     int argc;
  108.  
  109.     /* Parse the arguments to break words and strip quotes.  N.B. the
  110.      * main program can determine that the arument was quoted by inspecting
  111.      * the preceeding character */
  112.  
  113.     argc = 0;
  114.     if (line == NULL) goto endline;
  115.     for (;;)
  116.     {   while (*line == ' ' || *line == '\t' || *line == '\n') line++;
  117.         if (*line == 0) break;
  118.         if (argc == 32)
  119.         {   argc = 0;
  120.             goto endline;
  121.         }
  122.         if (*line == '"')
  123.         {   argv[argc] = ++line;
  124.             while (*line != '"')
  125.             {   if (*line == 0)
  126.                 {   argc = 0;
  127.                     goto endline;
  128.                 }
  129.                 line++;
  130.             }
  131.         }
  132.         else
  133.         {   argv[argc] = line;
  134.             while (*line != ' ' && *line != '\t' && *line != '\n')
  135.             {   if (*line == 0)
  136.                 {   argc++;
  137.                     goto endline;
  138.                 }
  139.                 line++;
  140.             }
  141.         }
  142.         *line++ = 0;
  143.         argc++;
  144.     }
  145. endline:
  146.  
  147.     /* Set up the standard input/output files */
  148.  
  149.     errfh = Open("*", MODE_OLDFILE);
  150.     if (errfh == NULL)
  151.     {   retcode = 20;
  152.         goto tidyexit;
  153.     }
  154.  
  155.     /* Call the main program  */
  156.  
  157.     main(argc, argv);
  158.  
  159.     /* Tidy up and exit */
  160.  
  161. tidyexit:
  162.     if (errfh) Close(errfh);
  163.  
  164.     XCEXIT(retcode);
  165. }
  166.  
  167. /* Main program */
  168.  
  169. void main(int argc, char **argv)
  170. {   char *s;
  171.     int *ip, i, ch;
  172.     int xsize, ysize, ssize, xoff, yoff, xden, yden, pden;
  173.  
  174.     /* Open the libraries */
  175.  
  176.     PSbase = OpenLibrary("post.library", POSTVERNO);
  177.     if (PSbase == NULL)
  178.     {   errmsg("can't open post.library");
  179.         goto errorexit;
  180.     }
  181.  
  182.     /* Parse the arguments and keywords.  See the usage string below */
  183.  
  184.     argc--;
  185.     argv++;
  186.     if (argc == 0 || (argc == 1 && strcmp(*argv, "?") == 0)) goto usage;
  187.  
  188.     while (argc--)
  189.     {   s = *argv++;
  190.         i = -1;
  191.         if (s[-1] != '"')
  192.             for (;;)
  193.             {   i++;
  194.                 if (argkey[i] == NULL)
  195.                 {   i = -1;
  196.                     break;
  197.                 }
  198.                 if (stricmp(s, argkey[i]) == 0) break;
  199.             }
  200.         switch (i)
  201.         {   case  0:    /* PRINT */
  202.                 if (argc == 0) goto badargs;
  203.                 argc--;
  204.                 argprint = *argv++;
  205.                 break;
  206.  
  207.             case  1:    /* SIZE */
  208.                 if (argc == 0) goto badargs;
  209.                 argc--;
  210.                 if (argsizec == 5) goto badargs;
  211.                 argsizev[argsizec++] = *argv++;
  212.                 break;
  213.  
  214.             case  2:    /* MEM */
  215.                 if (argc == 0) goto badargs;
  216.                 argc--;
  217.                 if (argmemc == 5) goto badargs;
  218.                 argmemv[argmemc++] = *argv++;
  219.                 break;
  220.  
  221.             default:
  222.                 if (argfilec == 5) goto badargs;
  223.                 argfilev[argfilec++] = s;
  224.         }
  225.     }
  226.     if (argprint == NULL) goto badargs;
  227.  
  228.     /* Get up the default page size from the printer preferences */
  229.  
  230.     bitmap.BytesPerRow = 1;
  231.     bitmap.Rows = 1;
  232.     bitmap.Flags = 0;
  233.     bitmap.Depth = parm.page.depth = 3;
  234.     setprinter();
  235.     parm.page.xoff = 0;
  236.     parm.page.yoff = 0;
  237.     if (prport == NULL)
  238.     {   errmsg("can't open printer device");
  239.         goto errorexit;
  240.     }
  241.     parm.page.ydir = -1;
  242.  
  243.     /* Parse the "SIZE xyod..s..p.bc." options */
  244.  
  245.     xsize = ysize = ssize = xden = yden = pden = 0;
  246.     for (i = 0; i < argsizec; i++)
  247.     {   s = argsizev[i];
  248.         for (;;)
  249.         {   ch = *s++;
  250.             if (ch == 0) break;
  251.             ch = tolower(ch);
  252.             switch (ch)
  253.             {   case 'x':
  254.                     if      (tolower(*s) == 'o')
  255.                     {   s++;
  256.                         if (!strtoint(&s, &xoff)) goto badvalue;
  257.                         parm.page.xoff = xoff;
  258.                         continue;
  259.                     }
  260.                     else if (tolower(*s) == 'd')
  261.                     {   s++;
  262.                         ip = &xden;
  263.                     }
  264.                     else
  265.                         ip = &xsize;
  266.                     break;
  267.  
  268.                 case 'y':
  269.                     if      (tolower(*s) == 'o')
  270.                     {   s++;
  271.                         if (!strtoint(&s, &yoff)) goto badvalue;
  272.                         parm.page.yoff = yoff;
  273.                         continue;
  274.                     }
  275.                     else if (tolower(*s) == 'd')
  276.                     {   s++;
  277.                         ip = &yden;
  278.                     }
  279.                     else
  280.                         ip = &ysize;
  281.                     break;
  282.  
  283.                 case 's':
  284.                     ip = &ssize;
  285.                     break;
  286.  
  287.                 case 'p':
  288.                     ip = &pden;
  289.                     break;
  290.  
  291.                 case 'd':
  292.                 {   if (!strtoint(&s, &xden)) goto badvalue;
  293.                     yden = xden;
  294.                     continue;
  295.                 }
  296.  
  297.                 case 'b':
  298.                     parm.page.depth = 1;
  299.                     continue;
  300.  
  301.                 case 'c':
  302.                     ch = *s;
  303.                     if      (ch == '3')
  304.                     {   s++;
  305.                         parm.page.depth = 3;
  306.                     }
  307.                     else if (ch == '4')
  308.                     {   s++;
  309.                         parm.page.depth  = 4;
  310.                     }
  311.                     else
  312.                         parm.page.depth = 3;
  313.                     continue;
  314.  
  315.                 default:
  316.                     goto badvalue;
  317.             }
  318.             if (!strtoint(&s, ip)) goto badvalue;
  319.         }
  320.     }
  321.     if (xden != 0) parm.page.xden = xden;
  322.     if (yden != 0) parm.page.yden = yden;
  323.     if (xsize != 0) parm.page.xsize = xsize;
  324.     if (ysize != 0) parm.page.ysize = ysize;
  325.     if (pden != 0)
  326.     {   prden = pden;
  327.         setprintden();
  328.     }
  329.  
  330.     /* Parse the "MEM fhlv.." options */
  331.  
  332.     for (i = 0; i < argmemc; i++)
  333.     {   s = argmemv[i];
  334.         for (;;)
  335.         {   ch = *s++;
  336.             if (ch == 0) break;
  337.             ch = tolower(ch);
  338.             switch (ch)
  339.             {   case 'f':
  340.                     ip = &parm.memflen;
  341.                     break;
  342.  
  343.                 case 'h':
  344.                     ip = &parm.memhlen;
  345.                     break;
  346.  
  347.                 case 'l':
  348.                     ip = &parm.memllen;
  349.                     break;
  350.  
  351.                 case 'v':
  352.                     ip = &parm.memvlen;
  353.                     break;
  354.  
  355.                 default:
  356.                     goto badvalue;
  357.             }
  358.             if (!strtoint(&s, ip)) goto badvalue;
  359.         }
  360.     }
  361.  
  362.     /* Set up the color map according to the number of bitplanes */
  363.  
  364.     colormap.Count = 1 << parm.page.depth;
  365.     if (parm.page.depth == 1)
  366.         colormap.ColorTable = (APTR) bcolors;
  367.     else
  368.         colormap.ColorTable = (APTR) ccolors;
  369.  
  370.     parm.page.ybase = 0;
  371.     parm.page.yheight = parm.page.ysize;
  372.     if (ssize != 0 && ssize < parm.page.ysize) parm.page.ysize = ssize;
  373.     if (parm.page.xsize == 0 || parm.page.ysize == 0)
  374.     {   errmsg("page size not set in preferences");
  375.         goto errorexit;
  376.     }
  377.     parm.page.xbytes = (parm.page.xsize + 15) >> 3 & 0xfffffffe;
  378.     parm.page.len = parm.page.xbytes * parm.page.ysize;
  379.  
  380.     /* Allocate the page buffer */
  381.  
  382.     for (i = 0; i < parm.page.depth; i++)
  383.     {   if ((parm.page.buf[i] =
  384.                 AllocMem(parm.page.len, MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
  385.         {   errmsg("can't get page buffer");
  386.             goto errorexit;
  387.         }
  388.     }
  389.  
  390.     /* Initialise the bitmap */
  391.  
  392.     bitmap.BytesPerRow = parm.page.xbytes;
  393.     bitmap.Rows = parm.page.ysize;
  394.     bitmap.Flags = 0;
  395.     bitmap.Depth = parm.page.depth;
  396.     memcpy((char *) bitmap.Planes, (char *) parm.page.buf,
  397.            sizeof bitmap.Planes);
  398.  
  399.     /* Open the print file and check the header */
  400.  
  401.     printfile = fopen(argprint, "r");
  402.     if (printfile == NULL)
  403.     {   errmsg("can't open print file\n");
  404.         goto errorexit;
  405.     }
  406.     s = "%!PS-Adobe-";
  407.     while (*s)
  408.     {   ch = fgetc(printfile);
  409.         if (ch != *s++) goto pferror;
  410.     }
  411.     for (;;)
  412.     {   ch = fgetc(printfile);
  413.         if (ch == '\n') break;
  414.         if (ch == EOF) goto pferror;
  415.     }
  416.     prologue = 1;
  417.     trailer = 0;
  418.  
  419.     /* Initialise for interpretation */
  420.  
  421.     insertbreak();
  422.     SetExcept(~0, SIGBREAKF_CTRL_C);
  423.     breakset = 1;
  424.     insertftrap();
  425.     ftrapset = 1;
  426.  
  427.     parm.copyfunc = (APTR) copypage;
  428.  
  429.     parm.infh = Input();
  430.     parm.outfh = Output();
  431.     parm.errfh = errfh;
  432.  
  433.     arec = PScreateact(&parm);
  434.     if (arec == 0)
  435.     {   errmsg("can't get memory");
  436.         goto errorexit;
  437.     }
  438.     if ((unsigned) arec <= errmax)
  439.     {   arec = 0;
  440.         retcode = 10;
  441.         goto tidyexit;
  442.     }
  443.  
  444.     /* Interpret the argument files */
  445.  
  446.     for (i = 0; i < argfilec; i++)
  447.         if (PSintstring(arec, argfilev[i],
  448.                         -1, PSFLAGFILE|PSFLAGCLEAR|PSFLAGERASE) != 0)
  449.         {   retcode = 10;
  450.             goto tidyexit;
  451.         }
  452.  
  453.     /* Interpret the prologue and each page */
  454.  
  455.     for (;;)
  456.     {   if (trailer) break;
  457.         splitpage();
  458.         if (retcode != 0) break;
  459.         ybase = 0;
  460.         if (PSintstring(arec,
  461.                         prologue ?
  462.             "(t:postband.ps) run" :
  463.             "currentband 1 sub{setband (t:postband.ps) run} for 0 setband",
  464.                         -1, PSFLAGSTRING) != 0)
  465.         {   retcode = 10;
  466.             break;
  467.         }
  468.         prologue = 0;
  469.     }
  470.  
  471.     goto tidyexit;
  472.  
  473.     /* File format error */
  474.  
  475. pferror:
  476.     errmsg("print file not PostScript conforming");
  477.     goto errorexit;
  478.  
  479.     /* Argument errors and usage query */
  480.  
  481. badargs:
  482.     errmsg("arguments bad, or value missing");
  483.     goto badusage;
  484.  
  485. badvalue:
  486.     errmsg("argument bad value");
  487.  
  488. badusage:
  489.     retcode = 20;
  490.  
  491. usage:
  492.     errmsg("usage:\n"
  493.     "    postband [files...] PRINT file [SIZE xyod..s..p.bc.] [MEM fhlv..]");
  494.     goto tidyexit;
  495.  
  496.     /* Tidy up and exit */
  497.  
  498. errorexit:
  499.     retcode = 20;
  500.  
  501. tidyexit:
  502.     DeleteFile("t:postband.ps");
  503.     if (printfile) fclose(printfile);
  504.  
  505.     if (breakset)
  506.     {   SetExcept(0, SIGBREAKF_CTRL_C);
  507.         deletebreak();
  508.         breakset = 0;
  509.     }
  510.     if (ftrapset)
  511.     {   deleteftrap();
  512.         ftrapset = 0;
  513.     }
  514.  
  515.     if (arec) PSdeleteact(arec);
  516.  
  517.     for (i = 0; i < parm.page.depth; i++)
  518.         if (parm.page.buf[i])
  519.         {   FreeMem(parm.page.buf[i], parm.page.len);
  520.             parm.page.buf[i] = NULL;
  521.         }
  522.  
  523.     if (propen) CloseDevice((struct IORequest *) &prreq);
  524.     if (prport) DeletePort(prport);
  525.  
  526.     if (PSbase)  CloseLibrary(PSbase);
  527. }
  528.  
  529. /* Print a string to a DOS file handle */
  530.  
  531. void prints(BPTR fh, char *string)
  532. {   Write(fh, string, strlen(string));
  533. }
  534.  
  535. /* Display an error message */
  536.  
  537. void errmsg(char *string)
  538. {   prints(errfh, "postband: ");
  539.     prints(errfh, string);
  540.     prints(errfh, "\n");
  541. }
  542.  
  543. /* Open the printer device and set up the page size */
  544.  
  545. void setprinter(void)
  546. {   if (propen == 0)
  547.     {   if (OpenDevice("printer.device", 0,
  548.                        (struct IOReqest *) &prreq, 0) != 0)
  549.             return;
  550.         propen = 1;
  551.     }
  552.     if (prport == NULL)
  553.     {   prport = CreatePort(NULL, 0);
  554.         if (prport == NULL) return;
  555.         prreq.io_Message.mn_ReplyPort = prport;
  556.         prsig = 1 << prport->mp_SigBit;
  557.         prdata = (struct PrinterData *) prreq.io_Device;
  558.         prextdata = &prdata->pd_SegmentData->ps_PED;
  559.         prprefs = &prdata->pd_Preferences;
  560.         prden = prprefs->PrintDensity;
  561.     }
  562.     if ((prprefs->PrintShade & SHADE_COLOR) == 0) parm.page.depth = 1;
  563.     setprintden();
  564. }
  565.  
  566. /* Set the printer density */
  567.  
  568. void setprintden(void)
  569. {   int pxsize, pysize;
  570.  
  571.     /* New density, call the device driver to change its extended data.  No
  572.      * error check */
  573.  
  574.     if (prden > 7) prden = 7;
  575.     if (prden != prprefs->PrintDensity)
  576.     {   prreq.io_Command = PRD_DUMPRPORT;
  577.         prrast.BitMap = &bitmap;
  578.         prreq.io_RastPort = &prrast;
  579.         prreq.io_ColorMap = (struct ColorMap *) &colormap;
  580.         prreq.io_Modes = 0;
  581.         prreq.io_SrcX = 0;
  582.         prreq.io_SrcY = 0;
  583.         prreq.io_SrcWidth = 1;
  584.         prreq.io_SrcHeight = 1;
  585.         prreq.io_DestCols = 1;
  586.         prreq.io_DestRows = 1;
  587.         prreq.io_Special = (SPECIAL_DENSITY1 * prden) | SPECIAL_NOPRINT;
  588.         prprefs->PrintDensity = prden;
  589.         DoIO((struct IORequest *) &prreq);
  590.     }
  591.  
  592.     /* Extract the page size and density from the printer device preferences
  593.      * and extended data */
  594.  
  595.     parm.page.xden = prextdata->ped_XDotsInch;
  596.     parm.page.yden = prextdata->ped_YDotsInch;
  597.     if      (prprefs->PrintFlags & PIXEL_DIMENSIONS)
  598.     {   pxsize = prprefs->PrintMaxWidth;
  599.         pysize = prprefs->PrintMaxHeight;
  600.     }
  601.     else if (prprefs->PrintFlags &
  602.                 (BOUNDED_DIMENSIONS|ABSOLUTE_DIMENSIONS))
  603.     {   pxsize = prprefs->PrintMaxWidth * parm.page.xden / 10;
  604.         pysize = prprefs->PrintMaxHeight * parm.page.yden / 10;
  605.     }
  606.     if (pxsize != 0) parm.page.xsize = pxsize;
  607.     if (pysize != 0) parm.page.ysize = pysize;
  608. }
  609.  
  610. /* String to integer conversion; digits only, with error check */
  611.  
  612. int strtoint(char **sp, int *ip)
  613. {   char *s = *sp;
  614.     int i = 0;
  615.     int ch;
  616.     for (;;)
  617.     {   ch = *s;
  618.         if (ch < '0' || ch > '9') break;
  619.         i = i * 10 + (ch - '0');
  620.         s++;
  621.     }
  622.     if (s == *sp)
  623.         return 0;
  624.     else
  625.     {   *sp = s;
  626.         *ip = i;
  627.         return 1;
  628.     }
  629. }
  630.  
  631. /* Signal an interrupt */
  632.  
  633. void __saveds sigint()
  634. {   PSsignalint(arec, 1);
  635. }
  636.  
  637. /* Signal a floating point error */
  638.  
  639. void __saveds sigfpe()
  640. {   PSsignalfpe(arec);
  641. }
  642.  
  643. /* Copy the page to the output */
  644.  
  645. void __saveds __asm copypage(register __d0 int num)
  646. {   ioerror = 0;
  647.     printpage();
  648.     if (ioerror) PSerror(arec, ioerror);
  649. }
  650.  
  651. /* Print the page */
  652.  
  653. void printpage()
  654. {   ULONG sig;
  655.     UWORD prflags;
  656.  
  657.     /* Disable break exceptions so we can wait on the signal instead */
  658.  
  659.     SetExcept(0, SIGBREAKF_CTRL_C);
  660.     breakset = 0;
  661.  
  662.     /* First check the printer is ready */
  663.  
  664.     prreq.io_Command = PRD_QUERY;
  665.     ((struct IOStdReq *) &prreq)->io_Data = (APTR) prstatus;
  666.     if (DoIO((struct IORequest *) &prreq))
  667.     {   ioerror = errioerror;
  668.         return;
  669.     }
  670.     if (((struct IOStdReq *) &prreq)->io_Actual == 1 && prstatus[0] & 3 != 0)
  671.         errmsg("printer not ready (CTRL/C to abort)");
  672.  
  673.     /* Now dump the page */
  674.  
  675.     prrast.BitMap = &bitmap;
  676.     prreq.io_Command = PRD_DUMPRPORT;
  677.     prreq.io_RastPort = &prrast;
  678.     prreq.io_ColorMap = (struct ColorMap *) &colormap;
  679.     prreq.io_Modes = 0;
  680.     prreq.io_SrcX = 0;
  681.     prreq.io_SrcY = 0;
  682.     prreq.io_SrcWidth = parm.page.xsize;
  683.     prreq.io_SrcHeight = parm.page.ysize;
  684.     prreq.io_Special = (SPECIAL_DENSITY1 * prden) | SPECIAL_TRUSTME;
  685.     if (ybase + parm.page.ysize >= parm.page.yheight)
  686.         prreq.io_SrcHeight = parm.page.yheight - ybase;
  687.     else
  688.         prreq.io_Special |= SPECIAL_NOFORMFEED;
  689.     if (prextdata->ped_MaxXDots != 0)
  690.         if (prreq.io_SrcWidth > prextdata->ped_MaxXDots)
  691.             prreq.io_SrcWidth = prextdata->ped_MaxXDots;
  692.     if (prextdata->ped_MaxYDots != 0)
  693.         if (prreq.io_SrcHeight > prextdata->ped_MaxYDots)
  694.             prreq.io_SrcHeight = prextdata->ped_MaxYDots;
  695.     prreq.io_DestCols = prreq.io_SrcWidth;
  696.     prreq.io_DestRows = prreq.io_SrcHeight;
  697.     ybase += prreq.io_SrcHeight;
  698.     prflags = prprefs->PrintFlags;
  699.     prprefs->PrintFlags = prflags & ~DIMENSIONS_MASK | IGNORE_DIMENSIONS;
  700.     prprefs->PrintAspect = ASPECT_HORIZ;
  701.  
  702.     /* We use asynchronous IO so we can abort it with a CTRL/C */
  703.  
  704.     SendIO((struct IORequest *) &prreq);
  705.  
  706.     for (;;)
  707.     {   sig = Wait(prsig | SIGBREAKF_CTRL_C);
  708.         if (sig & SIGBREAKF_CTRL_C)
  709.         {   AbortIO((struct IORequest *) &prreq);
  710.             WaitIO((struct IORequest *) &prreq);
  711.             ioerror = errioerror;
  712.             break;
  713.         }
  714.         if (GetMsg(prport))
  715.             break;
  716.     }
  717.     if (prreq.io_Error != 0) ioerror = errioerror;
  718.  
  719.     /* Restore break exceptions */
  720.  
  721.     SetExcept(~0, SIGBREAKF_CTRL_C);
  722.     breakset = 1;
  723.  
  724.     prprefs->PrintFlags = prflags;
  725. }
  726.  
  727. /* Split the prologue or next page of the print file into the temp file */
  728.  
  729. void splitpage(void)
  730. {   FILE *tempfile;
  731.     char *s;
  732.     int matched, ch;
  733.  
  734.     tempfile = fopen("t:postband.ps", "w");
  735.     if (tempfile == NULL)
  736.     {   errmsg("can't open temporary file");
  737.         retcode = 20;
  738.         return;
  739.     }
  740.  
  741.     matched = 0;
  742.     for (;;)
  743.     {   ch = fgetc(printfile);
  744.  
  745.         /* Comment lines are not copied */
  746.  
  747.         if (ch == '%')
  748.         {   ch = fgetc(printfile);
  749.  
  750.             /* %% Comments may be a trailer */
  751.  
  752.             if (ch == '%')
  753.             {   ch = fgetc(printfile);
  754.                 if      (ch == 'P')
  755.                 {   s = "age:";
  756.                     while (*s)
  757.                     {   ch = fgetc(printfile);
  758.                         if (ch != *s++) goto nomatch;
  759.                     }
  760.                     matched = 1;
  761.                 }
  762.                 else if (ch == 'T')
  763.                 {   s = "railer";
  764.                     while (*s)
  765.                     {   ch = fgetc(printfile);
  766.                         if (ch != *s++) goto nomatch;
  767.                     }
  768.                     if (prologue) goto pferror;
  769.                     matched = 1;
  770.                     trailer = 1;
  771.                 }
  772.             }
  773.  
  774.             /* Skip the rest of the comment */
  775.  
  776. nomatch:    if (ch == EOF) goto pferror;
  777.             for (;;)
  778.             {   ch = fgetc(printfile);
  779.                 if (ch == '\n') break;
  780.                 if (ch == EOF) goto pferror;
  781.             }
  782.         }
  783.  
  784.         /* All other lines are copied to the temp file */
  785.  
  786.         else
  787.         {   for (;;)
  788.             {   if (ch == EOF) goto pferror;
  789.                 if (fputc(ch, tempfile) == EOF) goto tferror;
  790.                 if (ch == '\n') break;
  791.                 ch = fgetc(printfile);
  792.             }
  793.         }
  794.         if (matched) break;
  795.     }
  796.     if (fclose(tempfile) == EOF) goto tferror;
  797.     return;
  798.  
  799. pferror:
  800.     errmsg("print file not conforming or io error");
  801.     goto errorexit;
  802.  
  803. tferror:
  804.     errmsg("error with temporary file");
  805.  
  806. errorexit:
  807.     fclose(tempfile);
  808.     retcode = 20;
  809. }
  810.  
  811. /* End of file "postband.c" */
  812.